#ifndef _SCUDB_HASH_TABLE_H_
#define _SCUDB_HASH_TABLE_H_

#include "sd_global.h"
#include "sd_blist.h"

struct sd_MemoryAllocator;

typedef uint32 (*sd_HashFunc)(const void* key);
typedef int (*sd_HashKeyCompare)(const void* k1, const void* k2);

typedef struct sd_Hashtable
{
	struct sd_MemoryAllocator* ma;
	sd_HashFunc hash_func;     /* The function to get the hash code from a key */
	sd_HashKeyCompare key_cmp; /* The function to compare two keys */
	size_t total_count;        /* The total number of elements */
	size_t keysize;
	size_t elemsize;
	size_t hashsize;           /* The number of buckets */
	sd_Blist buckets[1];
}sd_Hashtable;

typedef struct sd_HashtableIterator
{
	sd_Hashtable* hashtable;
	int bucketIndex;
	sd_BlistIterator bucketIter;
}sd_HashtableIterator;

sd_Ret sd_HashtableCreate(sd_Hashtable** table, sd_HashFunc hash_func,sd_HashKeyCompare key_cmp,size_t hashsize, 
						  size_t bucketNodeSize, size_t keysize, size_t elemsize, struct sd_MemoryAllocator* ma);
sd_Ret sd_HashtableFree(sd_Hashtable* table);
sd_Ret sd_HashtableInsert(sd_Hashtable* table, const void* key, const void* elem);
sd_Ret sd_HashtableLookup(sd_Hashtable* table, const void* key, void* elem);
sd_Ret sd_HashtableUpdate(sd_Hashtable* table, const void* key, const void* elem);
sd_Ret sd_HashtableDelete(sd_Hashtable* table, const void* key);
sd_Ret sd_HashtableClear(sd_Hashtable* table);
sd_Ret sd_HashtableBegin(sd_Hashtable* table, sd_HashtableIterator* iter);
sd_Ret sd_HashtableNext(sd_HashtableIterator* iter);
sd_Ret sd_HashtableGet(sd_HashtableIterator* iter, void* elem);
sd_Ret sd_HashtableGetKey(sd_HashtableIterator* iter, void* elem);

/* Default hash function and compare function */
uint32 sd_HashFunc_uint32(const void* key);
int sd_HashKeyCompare_uint32(const void* k1, const void* k2);

uint32 sd_HashFunc_uint64(const void* key);
int sd_HashKeyCompare_uint64(const void* k1, const void* k2);


#endif
